(for Internet Explorer)
$ arr[0]="ABC"
$ arr[1]="DEF"
$ arr[2]="GHI"

$ echo "${arr[1]}"
DEF

$ echo ${#arr[@]}
3
参考
arr[0]="ABC"
… 配列に格納します。
"${arr[1]}"
… 配列の要素を返します。
${#arr[@]}
… 配列の要素数を返します。
arr=( "ABC" \
      "DEF" "GHI" )
for (( i = 0; i < ${#arr[@]}; i ++ ));do
  echo  "${arr[$i]}"
done
arr
arr
関連
空白で区切られたそれぞれの値でループ
arr=( "ABC" "DEF" "GHI" )
for  elem  in  "${arr[@]}" ;do
  echo  "$elem"
done
elem
elem
arr
arr
for 要素 in 配列 方式:
配列番号方式:
関連
for a in "${arr[@]}";do  echo $a ;done
… 配列の要素を一覧します。(改行あり)
arr
arr=("${arr[@]}" "add")
… 配列の末尾の要素の次に追加します。
break が使えますが、
break でループを抜けたか、
最後の要素までループしたかを
elem の値から判定することはできません。
echo "${arr[@]}"
… 配列の要素を一覧します。(フィールド形式。改行なし)
arr
… 配列をコピーします。
arr2=("${arr[@]}")
${!arr[@]}
… 配列の番号を一覧します。(フィールド形式)
$ fields="ABC DEF GHI"
$ echo $fields | cut -d" " -f2
DEF
$ echo $fields | cut -d" " -f1-3
ABC DEF GHI
$ echo $fields | cut -d" " -f1,3
ABC GHI
$ echo ${#arr}
11
fields="ABC DEF GHI"
for  elem  in  $fields ;do
  echo  $elem
done
参考
${#fields}
… 文字数
… cut コマンドは、区切り文字を指定して要素を参照
"$fields" ではなく $fields にしてください。
" " で囲まないときは、値に含まれる空白文字や改行文字を
フィールドに分割します。

ちなみに、配列のときは "${arr[@]}" のように " " で囲まなければ、
配列要素の中の空白文字を要素の区切りと判定してしまいます。
  declare -A  ObjectA  #// associative array
  ObjectA["Attr1"]="Value1"
  ObjectA[Attr2]="Value2"
  ObjectA["Attr3"]="Value3"

  echo  ${ObjectA["Attr1"]}  #// "Value1"
  echo  ${ObjectA["Attr2"]}  #// "Value2"
  echo  ${ObjectA[Attr3]}    #// "Value3"

  attr_name="Attr2"
  echo  ${ObjectA[$attr_name]}    #// "Value2"
  declare -A  ObjectA  #// associative array
  ObjectA=( [Attr1]="Value1" [Attr2]="Value2" )
  echo  ${ObjectA[Attr1]}  #// "Value1"
  echo  ${ObjectA["Attr2"]}  #// "Value2"
[ ] の中は文字列ですが、
" " で囲む必要はありません。
連想配列の基本
連想配列の初期化子
参考
連想配列の集合処理
  declare -A  ObjectA  #// associative array
  ObjectA["Attr1"]="Value1"
  ObjectA["Attr2"]="Value2"
  echo  ${!ObjectA[@]}  #// Attr1 Attr2
  echo  ${ObjectA[@]}   #// Value1 Value2
関数の中からグローバル変数として declare するには、-g オプションを指定します。
ただし、bash 4.2 から使えます。
その他
変数の型
#// global variables as associative arrray
declare -A  g_ObjectA
declare -A  g_ObjectB

function  InitObjs_func()
{
  g_ObjectA["Attr1"]="Value1"   #// g_ObjectA.Attr1 = "Value1"
  g_ObjectA["Attr2"]="Value2"

  g_ObjectB["Attr1"]="$( Attr_func g_ObjectA "Value1" )"
  g_ObjectB["Attr2"]="Value4"
}

function  Attr_func()
{
  local  self_name="$1"  #// または local  self ; CopyArray_func  self  "$1"
  local  AttrName="$2"

  eval echo "\${${self_name}[\$AttrName]}"  #// または echo  "${self[$AttrName]}"
}

InitObjs_func
for obj in  ${g_Objects[@]};do
  echo  "`Attr_func $obj "Attr2" `"   #// echo g_ObjectA.Attr2
done
関連
declare -A が無くても、ObjectA["Attr1"] を実行すると連想配列が作られます。
declare を関数内で実行するとローカル、関数の外で実行するとグローバルになります。
関数の引数には指定できません。 オブジェクトはグローバルにせざるを得ないでしょう。
bash ver3 のための擬似連想配列
g_ObjectA["Attr1"]="Value1"
bash ver4 で使える連想配列
bash ver3 でも使える bashlib 関数
SetAttr_func  g_ObjectA  "Attr1"  "Value1"
SetAttr_func の実装
eval "$self[$AttrName]=\"$Value\""
属性(メンバー変数)
メソッド(メンバー関数)
関連
#!/bin/bash -eE

export  g_Objects=( "g_ObjectA"  "g_ObjectB" )
for obj  in  ${g_Objects[@]};do  declare -A $obj  ; done
                                     #// associative array
function  InitObjs_func()
{
  g_ObjectA["Class"]="AClass"
  g_ObjectA["Attr1"]="ValueA"
  g_ObjectA["doA_method"]="AClass.doA_method"

  g_ObjectB["Class"]="BClass"
  g_ObjectB["Attr1"]="ValueB"
  g_ObjectB["doA_method"]="BClass.doA_method"
}


function  Main_func()
{
  local  obj

  InitObjs_func
  for obj in ${g_Objects[@]};do
    $( Attr_func $obj "doA_method" )  $obj
  done
}

function  AClass.doA_method()
{
  local  self="$1"
  echo "AClass.doA_method( $self )"
}

function  BClass.doA_method()
{
  local  self="$1"
  echo "BClass.doA_method( $self )"
}

function  Attr_func()
{
  local  self="$1"
  local  AttrName="$2"

  eval echo "\${${self}[\$AttrName]}"
}

Main_func
g_SetupFileNames=( "./Child1.sh"  "./Child2.sh" )

function  Main_func()
{
  local  name_sh ;  local  result

  for  name_sh  in  ${g_SetupFileNames[@]};do
    $name_sh  --FuncA_func  --Param1=Value1 --Param2=Value2
  done

  for  name_sh  in  ${g_SetupFileNames[@]};do
    result=`$name_sh  --FuncB_func  --Param1=Value1`
    echo  "\$result = $result"
  done
}
Main.sh
g_AllArguments="$@"
g_FuncName=${1#--*}  #// cut -- from $1

function  Main_func()
{
  $g_FuncName  $g_AllArguments
}

function  FuncA_func()
{
  echo  "FuncA_func in Package1.sh"
}

function  FuncB_func()
{
  echo  "FuncB_func in Package1.sh"
}
Child1.sh
g_AllArguments="$@"
g_FuncName=${1#--*}  #// cut -- from $1

function  Main_func()
{
  $g_FuncName  $g_AllArguments
}

function  FuncA_func()
{
  echo  "FuncA_func in Package1.sh"
}

function  FuncB_func()
{
  echo  "FuncB_func in Package1.sh"
}
Child2.sh
関連
関数名は、クラス名+Class+ピリオド+メソッド名_method。
クラス名は、単語の先頭は大文字、後は小文字。(Java準拠)
メソッド名は、先頭の単語はすべて小文字、後の単語は先頭文字のみ大文字。(Java準拠)
メソッドに相当する関数の第1引数は、オブジェクトの名前(=連想配列の
名前)。 関数内では、self という変数名にする。
function  SampleClass.doSample_method()
{
  local  self="$1"
サンプル
オブジェクトの名前を、ファイル名、または、第1パラメーターにします。
メソッド名を、関数名と同じ、パラメーターなしのオプションにします。
メソッドのパラメーターを、パラメーターありのオプションにします。
#!/bin/bash -x
                  #// -x option echos commands
set -e            #// -e option does not continue, if error was raised

cp NoFile NoFolder
echo  Error ignored

set +e            #// +e option does not exit shell, if error was raised
set -e を実行すると、エラーが発生したときに続きを実行しないようになります。
エラーが発生したと判定するときは、実行したコマンドの終了コードが 0 以外のときです。
set +e で、set -e を無効にしているのは、シェルから入力したコマンドでエラーが
発生しても、シェルが終了してしまうのを避けるためです。
if [ ! -e NoFile ]; then unset ERROR;${ERROR:?not found NoFile};fi
m-toda@nk4lx5:~$ unset ERROR;${ERROR:?This is error test}
-bash: ERROR: This is error test
unset ERROR;${ERROR:?Error message}
変数が定義されていなければエラーにする構文 ${VAR:?message} を応用して、
エラーを発生させる方法です。
サンプル
サンプル
ファイルがないときにエラーにする
#!/bin/bash -eE
                  #// -eE option does not continue, if error was raised

echo  success && echo AND
echo  success || echo OR
cp NoFile NoFolder && echo AND
cp NoFile NoFolder || echo OR
cp NoFile NoFolder || cp NoFile NoFolder
echo  Error ignored
&& は、&& の左のコマンドの終了コードが 0 (正常)だったときに、&& の右のコマンドを実行します。
|| は、|| の左のコマンドの終了コードが 0 以外(エラー)だったときに、|| の右のコマンドを実行します。
&& または || の左のコマンドがエラーになっても、set -e によって、スクリプトが中断されることは
ありません。 && または || の左のコマンドがエラーになったら中断します。
#!/bin/bash -xe
                  #// -x option echos commands
                  #// -e option does not continue, if error was raised

cp NoFile NoFolder
echo  Error ignored
-xe は、-x オプションと -e オプションの両方を指定するという意味です。
上下のシェルスクリプトは、同じ内容です。
echo  success && echo AND ; echo after
echo  success || echo OR  ; echo after
; の後は、&& || の影響を受けないで、必ず実行します。
これは非推奨です。
推奨
これは非推奨です。
推奨
(ただし、終了コードは 0 になってしまいます。)
参考
関数呼び出しの後に && または || を記述すると、関数内でエラーが発生しても、すぐに
返らないで、続きを実行してしまいます。
これは非推奨です。
推奨
非推奨
推奨
関連
0    EXIT     exit the program, not actual signal
1     HUP    hang up, will actually cause a daemon to reread the configuration file
2     INT   Interrupt or stop running, you can do this with Ctrl+C
3    QUIT  quit key, CTRL+SHIFT or CTRL+SHFT+\
9     KILL  stop immediately regardless of anything else, this is like an emergency kill switch
15    TERM  terminate nicely if at all possible
18    CONT  continue execution, this will start a stopped process
20    TSTP  stop executing, continue
DEBUG execute commands specified in trap statement
ERR     execute commands specified in trap statement after each command
trap 'echo trapped' EXIT
#!/bin/bash -xe
                  #// -x option echos commands
                  #// -e option does not continue, if error was raised

cp NoFile NoFolder
echo  Error ignored
先頭の #!/bin/bash に -x を付けると、実行しているコマンドを表示しながら実行します。
-v をつけた場合、関数の中に入ると表示しなくなります。
user1@linux:~$ ~/temporary.sh
+ cp NoFile NoFolder
cp: `NoFile' を stat できません: そのようなファイルやディレクトリはありません
temporary.sh
シェルの表示内容
function  err_trap {
  echo  ""
  if [ "${#FUNCNAME[@]}" == "2" ]; then
    echo  "(Hint) Line number is shown by following trap command in the top of script."
    echo  "  " trap \'echo "\$BASH_SOURCE\\(\$LINENO\\)"\' DEBUG
  else
    for(( i=1; i < ${#FUNCNAME[@]}; i++ ));do
      echo "callstack[$i]=${FUNCNAME[$i]}  ${BASH_SOURCE[$i-1]}(${BASH_LINENO[$i-1]})"
    done
    echo  "(Hint) Line number in ${FUNCNAME[1]} function is shown by following trap command in the top of ${FUNCNAME[1]} function."
    echo  "  " trap \'echo "\$BASH_SOURCE\\(\$LINENO\\) in \$FUNCNAME\\(\\)"\' DEBUG
  fi
}
trap 'set +x ; err_trap' EXIT
main_func
trap '' EXIT
次のようにすると、main_func の中でエラーが発生すると、コールスタックを表示します。
関数の外の場合
関数の中の場合
先頭行のオプションについては、
で "set [" を検索してください。
trap 'echo "$LINENO: $BASH_COMMAND"' DEBUG
-x が無くても、下記を記述すると、コマンドラインを表示しながら実行します。行番号付き。
ただし、関数の中に入ると、表示しなくなります。
trap 'read -p "$LINENO: $BASH_COMMAND" key' DEBUG
下記を記述すると、ステップ実行します。 Enter キーを押すと、1行進みます。
ステップ・インはできません。 ステップ・オーバーだけです。
./sample.sh: 行 369: 予期しないトークン `}' 周辺に構文エラー があります
} が関数の終了のときは、その関数の中で、if 〜 fi や case 〜 esac の対応関係が合っていません。
参考
→ BashSyntax (vbslib)
#!/bin/bash -eE

function  Main_func()
{
  local var1=$( NotDefined_func "a" )
  echo  "<ERROR msg=\"Do not come here 1\"/>"

  local var=`NotDefined "a"`
  echo  "<ERROR msg=\"Do not come here 2\"/>"

  local var; var=$( NotDefined_func "a" )
  echo  "<ERROR msg=\"Do not come here 3\"/>"
}

Main_func
$ ./temp.sh
./temp.sh: line 5: NotDefined_func: コマンドが見つかりません
<ERROR msg="Do not come here 1"/>
./temp.sh: line 8: NotDefined_func: コマンドが見つかりません
<ERROR msg="Do not come here 2"/>
./temp.sh: line 11: NotDefined_func: コマンドが見つかりません
temp.sh
呼び出すコマンドや関数が見つからないとき、関数の返り値を local コマンドと同時に
使用すると、続きを実行してしまいます。(下記var1への代入)
local コマンドと同時でなければ、正しく実行を中断します。(下記var2への代入)
実行結果
g_Var="1"

function  Caller_func()
{
  local  tmp
  tmp=`Called_func`  #// echo 出力を格納
  echo  "$tmp"       #// "output"
  echo  "$g_Var"     #// "1" のまま
}

function  Called_func()
{
  g_Var="a"     #// echo 出力が取得されるとき、グローバルの変更は無効
  echo  "output"
}
呼び出した関数の echo 出力を取得するとき、呼び出した関数の中でグローバル
変数の値を変更しても、リターンするときに元に戻ります。
(cache)